package org.zhangkun.jmsg.ui.swing;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

import org.zhangkun.jmsg.core.network.NetConnection;
import org.zhangkun.jmsg.util.GlobalVar;
import org.zhangkun.jmsg.util.StrUtil;

import com.l2fprod.common.swing.JLinkButton;

public class HostListDialog extends JFrame {
	private JTextField addresField;
	private JTextField portsField;
	private JTable table;
	private ArrayList<String> ips;
	private ArrayList<String> result;
	private static HostListDialog instance = null;
	private JTextField threads;

	public HostListDialog() {
		ips = NetConnection.instance.getAllIP();
		result = new ArrayList<String>();
		for (int i = 0; i < ips.size(); i++) {
			result.add(null);
		}
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent arg0) {
				instance.dispose();
				instance = null;
			}
		});
		JScrollPane scrollPane = new JScrollPane();
		getContentPane().add(scrollPane, BorderLayout.CENTER);

		table = new JTable();
		table.setModel(new TableModel() {

			public void setValueAt(Object arg0, int arg1, int arg2) {
				// TODO Auto-generated method stub

			}

			public void removeTableModelListener(TableModelListener arg0) {
				// TODO Auto-generated method stub

			}

			public boolean isCellEditable(int arg0, int arg1) {
				// TODO Auto-generated method stub
				return false;
			}

			public Object getValueAt(int arg0, int arg1) {
				// TODO Auto-generated method stub
				return arg1 == 0 ? ips.get(arg0)
						: (result.get(arg0) == null ? "等待检测" : result.get(arg0));
			}

			public int getRowCount() {
				// TODO Auto-generated method stub
				return ips.size();
			}

			public String getColumnName(int arg0) {
				// TODO Auto-generated method stub
				return arg0 == 0 ? "IP" : "结果";
			}

			public int getColumnCount() {
				// TODO Auto-generated method stub
				return 2;
			}

			public Class<?> getColumnClass(int arg0) {
				// TODO Auto-generated method stub
				return String.class;
			}

			public void addTableModelListener(TableModelListener arg0) {
				// TODO Auto-generated method stub

			}
		});
		scrollPane.setViewportView(table);

		JPanel panel = new JPanel();
		FlowLayout flowLayout = (FlowLayout) panel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);
		getContentPane().add(panel, BorderLayout.NORTH);

		JLabel label = new JLabel("地址：");
		panel.add(label);

		addresField = new JTextField();
		panel.add(addresField);
		addresField.setColumns(20);

		JButton btnNewButton = new JLinkButton("添加");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (StrUtil.verifyIPAddres(addresField.getText())) {
					ips.add(addresField.getText());
					addresField.setText("");
				} else {
					JOptionPane.showMessageDialog(instance, "输入的IP地址不合法！");
				}
			}
		});
		panel.add(btnNewButton);

		JLabel label_1 = new JLabel("扫描端口：");
		panel.add(label_1);

		portsField = new JTextField();
		panel.add(portsField);
		portsField.setColumns(10);

		JLabel label_2 = new JLabel("线程：");
		panel.add(label_2);

		threads = new JTextField();
		threads.setText("3");
		panel.add(threads);
		threads.setColumns(3);

		JButton button = new JButton("启动扫描");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				new Thread() {
					public void run() {
						scan();
					}
				}.start();
			}
		});
		panel.add(button);

		JPanel panel_1 = new JPanel();
		getContentPane().add(panel_1, BorderLayout.EAST);
		panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.Y_AXIS));
		setSize(554, 400);
		setVisible(true);
	}

	private void scan() {

		for (int i = 0; i < ips.size(); i++) {
			result.set(i, null);
		}
		table.revalidate();
		table.repaint();
		if (!threads.getText().matches("\\d+")) {
			threads.setText("1");
		}
		int threadNum = Integer.parseInt(threads.getText());

		if (!portsField.getText().matches("\\d+(\\d+,)?(\\d+)?")) {
			portsField.setText("80," + GlobalVar.IPMSG_PORT);
		}

		int[] ports = new int[5];

		String[] ps = portsField.getText().split(",");
		ports = new int[ps.length];
		for (int i = 0; i < ps.length; i++)
			ports[i] = Integer.parseInt(ps[i]);

		// 启动发送线程
		ArrayList<ScanThread> allSendThread = new ArrayList<ScanThread>();
		for (int i = 0; i < threadNum; i++)
			allSendThread.add(new ScanThread(ports));

		for (int i = 0; i < ips.size(); i++) {
			System.out.println("扫描：" + ips.get(i));
			boolean send = false;
			while (!send) {
				for (int z = 0; z < allSendThread.size(); z++) {
					ScanThread st = allSendThread.get(z);
					if (st.waiting) {
						st.setIndex(i);
						st.waiting = false;
						send = true;
						break;
					}
				}
			}
		}
		System.out.println("等待线程退出");
		for (int i = 0; i < allSendThread.size(); i++) {
			ScanThread st = allSendThread.get(i);
			st.stop = true;
			while (st.isAlive())
				;
		}

	}

	private class ScanThread extends Thread {
		private int index;
		private boolean waiting = true;
		private boolean stop = false;
		private int[] ports;

		public ScanThread(int[] ports) {
			this.ports = ports;
			start();
		}

		public void setIndex(int index) {
			this.index = index;
		}

		public void run() {
			while (!stop) {
				if (waiting) {
					try {
						Thread.sleep(1);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				} else {
					int timeOut = 3000; // 超时应该在3钞以上
					InetAddress inetAddress;
					while (true) {
						try {
							inetAddress = InetAddress.getByName(ips.get(index));
							boolean status;
							try {
								status = inetAddress.isReachable(timeOut);
							} catch (IOException e) {
								// TODO Auto-generated catch block
								result.set(index, "该地址无法连接");
								break;
							}
							if (status) {
								result.set(index, "地址连接成功。");
								ArrayList<String> allSuccesPort = new ArrayList<String>();
								for (int i = 0; i < ports.length; i++) {
									int port = ports[i];
									Socket socket = null;
									try {
										socket = new Socket(ips.get(index),
												port);
									} catch (IOException e) {
										// TODO Auto-generated catch block
										continue;
									}
									allSuccesPort.add(port + "");
									socket.close();
								}
								if (allSuccesPort.size() == 0)
									result.set(index, result.get(index)
											+ "但是没有成功连接任何输入的端口。");
								else
									result.set(
											index,
											result.get(index)
													+ "成功连接的端口："
													+ StrUtil.joinStrings(
															allSuccesPort, ","));
							} else {
								result.set(index, "该地址无法连接");
							}
						} catch (Exception e) {
							result.set(index, "该地址无法连接");
						}
						break;
					}
					table.revalidate();
					table.repaint();
					waiting = true;
				}
			}
		}
	}

	public static void open() {
		if (instance == null) {
			instance = new HostListDialog();
		}
	}

}
